/*
 * ArchivoIndice.cpp
 *
 *  Created on: 31/03/2011
 */

#include "ArchivoIndice.h"
#include <string>

ArchivoIndice::ArchivoIndice(string unNombreDeArchivoIndice) {

	this->nombreDeArchivoIndice = unNombreDeArchivoIndice;

	//Crea el archivo y lo deja abierto en modo lectura - escritura binario
	this->archivoIndice.open(nombreDeArchivoIndice.c_str(), ios::in | ios::out | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
//	if (!this->archivoIndice.is_open()) {
//
//		/* limpia los flags de control de estado del archivo */
//		this->archivoIndice.clear();
//		throw string("El archivo no pudo ser abierto");
//	}

	this->archivoIndice.close();

}

void ArchivoIndice::abrirParaLeer() {
	//Abre el archivo y lo deja abierto en modo lectura binaria
	this->archivoIndice.open(nombreDeArchivoIndice.c_str(), ios::in  | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
	if (!this->archivoIndice.is_open()) {

		/* limpia los flags de control de estado del archivo */
		this->archivoIndice.clear();
		throw string("El archivo no pudo ser abierto para lectura");
	}
}

void ArchivoIndice::abrirParaEscribir() {
	//Abre el archivo y lo deja abierto en modo lectura binaria
	this->archivoIndice.open(nombreDeArchivoIndice.c_str(), ios::out | ios::app  | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
	if (!this->archivoIndice.is_open()) {

		/* limpia los flags de control de estado del archivo */
		this->archivoIndice.clear();
		throw string("El archivo no pudo ser abierto para escritura");
	}
}

int ArchivoIndice::escribir(RegistroIndice* unRegistroIndice) {

	//Obtengo la longitud del registro
	int longitudDelRegistro = unRegistroIndice->obtenerLongitud();

	//Me posiciono al final del archivo
	this->archivoIndice.seekp(0, ios_base::end);

	//Guardo el offset para usarlo como id al registro guardado
	int offset = this->archivoIndice.tellp();

	//Grabo como primer campo la longitud del registro
	this->archivoIndice.write((char*) &longitudDelRegistro, sizeof(int));

	//Paso el registro a binario
	char* binario = unRegistroIndice->aBinario();

	//Grabo como segundo campo el registro
	this->archivoIndice.write(binario, longitudDelRegistro);

	//Devuelvo el id al registro grabado
	return offset;

}

RegistroIndice* ArchivoIndice::leer(int idRegistroIndice) {

	/*El id del registro me da el offset donde se encuentra el
	 * primer campo a leer que es la longitud del registro */
	//Me posiciono en el campo longitud
	this->archivoIndice.seekg(idRegistroIndice, ios_base::beg);

	//Obtengo la longitud del registro
	int longitudDelRegistro;
	this->archivoIndice.read((char*) &longitudDelRegistro, sizeof(int));

	//Leo el registro en binario
	char* binario = new char[longitudDelRegistro];
	this->archivoIndice.read(binario,longitudDelRegistro);

	//Obtengo el registro indice
	RegistroIndice* registroIndice = new RegistroIndice();
	//Convierto el registro desde binario a un objeto RegistroRuta
	registroIndice->desdeBinario(binario, longitudDelRegistro);

	return registroIndice;

}

RegistroIndice* ArchivoIndice::leerSiguiente() {

	//Obtengo la longitud del registro
	int longitudDelRegistro;
	this->archivoIndice.read((char*) (&longitudDelRegistro),sizeof(int));

	//Leo el registro en binario
	char* binario = new char[longitudDelRegistro];
	this->archivoIndice.read(binario,longitudDelRegistro);

	//Obtengo el registro indice
	RegistroIndice* registroIndice = new RegistroIndice();
	//Convierto el registro desde binario a un objeto RegistroRuta
	registroIndice->desdeBinario(binario, longitudDelRegistro);

	return registroIndice;

}

void ArchivoIndice::cerrar() {
	this->archivoIndice.close();
}

ArchivoIndice::~ArchivoIndice() {
}

void ArchivoIndice::sobreescribir(){
	//Crea el archivo y lo deja abierto en modo lectura - escritura binario
	this->archivoIndice.open(nombreDeArchivoIndice.c_str(), ios::in | ios::out | ios::trunc | ios::binary);

	/* determina si tuvo éxito la apertura del archivo */
	if (!this->archivoIndice.is_open()) {

		/* limpia los flags de control de estado del archivo */
		this->archivoIndice.clear();
		throw string("El archivo no pudo ser sobreescrito");
	}

	this->archivoIndice.close();
}

